using System;
using System.Collections;
using System.Xml;

namespace LocalBoard.Domain
{
	/// <summary>
	/// Summary description for Message.
	/// </summary>
	public class Message
	{
		public Message(int id, int no, string subject, string body, string postedByUserName, string postedByUserId, int hits, DateTime date, Profile author, int boardId, int clubId, int replyToId, ArrayList replies, ArrayList comments, ArrayList attachments) : this(subject, body, postedByUserName, postedByUserId, author, boardId, clubId, replyToId)
		{
			_id = id;
			_no = no;
			_hits = hits;
			_date = date;
			_replies = replies;
			_comments = comments;
			_attachments = attachments;
		}
		public Message(string subject, string body, string postedByUserName, string postedByUserId, Profile author, int boardId, int clubId, int replyToId, String customData)
			: this(subject, body, postedByUserName, postedByUserId, author, boardId, clubId, replyToId)
		{
			_dataXml = new XmlDocument();
			_dataXml.LoadXml(customData);
		}
		public Message(string subject, string body, string postedByUserName, string postedByUserId, Profile author, int boardId, int clubId, int replyToId)
		{
			_subject = subject;
			_body = body;
			_postedByUserName = postedByUserName;
			_postedByUserId = postedByUserId;
			_author = author;
			_boardId = boardId;
			_clubId = clubId;
			_replyToId = replyToId;
		}

		private int _id;
		private int _no;
		private string _subject;
		private string _body;
		private string _postedByUserName;
		private string _postedByUserId;
		private int _hits;
		private DateTime _date;
		private Profile _author;
		private int _boardId;
		private int _clubId;
		private int _replyToId;
		private Message _replyTo = null;
		private ArrayList _replies;	//Message type
		private ArrayList _comments;	//Comment type
		private ArrayList _attachments; //Attachment type

		public int Id
		{
			get{return _id;}
//			set{_id = value;}
		}
		public int No
		{
			get{return _no;}
//			set{_no = value;}
		}
		public string Subject
		{
			get{return _subject;}
			set{_subject = value;}
		}
		public string Body
		{
			get{return _body;}
			set{_body = value;}
		}
		public string PostedByUserName
		{
			get{return _postedByUserName;}
//			set{_postedByUserName = value;}
		}
		public string PostedByUserId
		{
			get{return _postedByUserId;}
//			set{_postedByUserId = value;}
		}
		public int Hits
		{
			get{return _hits;}
			set{_hits = value;}
		}
		public DateTime Date
		{
			get{return _date;}
//			set{_date = value;}
		}
		public Profile Author
		{
			get{return _author;}
//			set{_author = value;}
		}
		public int BoardId
		{
			get{return _boardId;}
			set{_boardId = value;}
		}
		public int ClubId
		{
			get{return _clubId;}
		}
		/// <summary>
		/// This property is going to be obsolete upon implementation of ReplyTo lazy load
		/// </summary>
		public int ReplyToId
		{
			get{return _replyToId;}
//			set{_replyToId = value;}
		}
		[Obsolete("Not yet implemented", true)]
		public Message ReplyTo
		{
			//TODO: Implement Lazy Load
			get{return _replyTo;}
//			set{_replyTo = value;}
		}
		public ArrayList Replies
		{
			get{return _replies;}
//			set{_replies = value;}
		}
		public ArrayList Comments
		{
			get{return _comments;}
//			set{_comments = value;}
		}
		public ArrayList Attachments
		{
			get{return _attachments;}
//			set{_attachments = value;}
		}
		
		int _x = int.MinValue;
		public int X
		{
			get
			{
				if (_x == int.MinValue)
				{
					if (_dataXml != null)
					{
						XmlNode node = _dataXml.SelectSingleNode("/Message/@x");
						if (node != null)
						{
							try
							{
								_x = Convert.ToInt32(node.Value);
							}
							catch (Exception e) { }
						}
					}
					if (_x == int.MinValue)
						_x = 0;
				}
				return _x;
			}
			set
			{
				_x = value;
				SetAttributeValue("x", value.ToString());
			}
		}

		int _y = int.MinValue;
		public int Y
		{
			get
			{
				if (_y == int.MinValue)
				{
					if (_dataXml != null)
					{
						XmlNode node = _dataXml.SelectSingleNode("/Message/@y");
						if (node != null)
						{
							try
							{
								_y = Convert.ToInt32(node.Value);
							}
							catch (Exception e) { }
						}
					}
					if (_y == int.MinValue)
						_y = 0;
				}
				return _y;
			}
			set
			{
				_y = value;
				SetAttributeValue("y", value.ToString());
			}
		}

		int _z = int.MinValue;
		public int Z
		{
			get
			{
				if (_z == int.MinValue)
				{
					if (_dataXml != null)
					{
						XmlNode node = _dataXml.SelectSingleNode("/Message/@z");
						if (node != null)
						{
							try
							{
								_z = Convert.ToInt32(node.Value);
							}
							catch (Exception e) { }
						}
					}
					if (_z == int.MinValue)
						_z = 0;
				}
				return _z;
			}
			set
			{
				_z = value;
				SetAttributeValue("z", value.ToString());
			}
		}

		XmlDocument _dataXml = new XmlDocument();
		public XmlDocument DataXml
		{
			get { return _dataXml; }
		}

		private void SetAttributeValue(string attributeName, string value)
		{
			XmlNode node = _dataXml.SelectSingleNode("/Message/@" + attributeName);
			if (node == null)
			{
				XmlElement element = GetDocumentElement();
				XmlAttribute attr = _dataXml.CreateAttribute(attributeName);
				element.Attributes.Append(attr);
				node = attr;
			}
			node.Value = value;
		}

		private XmlElement GetDocumentElement()
		{
			XmlElement element = _dataXml.DocumentElement;
			if (element == null)
			{
				element = _dataXml.CreateElement("Message");
				_dataXml.AppendChild(element);
			}
			return element;
		}

		#region static member
		public static int GetMessageTypeId(Message message)
		{
			if(message is PollMessage)
				return 2;
			else
				return 1;
		}
		public static MessageType GetMessageType(int messageTypeId)
		{
			switch(messageTypeId)
			{
				case 2:
					return MessageType.PollMessage;
				case 1:
				default:
					return MessageType.Message;
			}
		}
		#endregion
	}
}
